/*
 *  Copyright 2010 dmakariev.
 * 
 */
package org.deltaset.faces.upload;

import javax.el.ELContext;
import javax.el.ValueExpression;
import javax.faces.component.UINamingContainer;
import javax.faces.context.FacesContext;
import javax.servlet.ServletRequestWrapper;
import org.apache.commons.fileupload.FileItem;
import org.deltaset.faces.FacesUtils;
import org.primefaces.webapp.MultipartRequest;

/**
 *
 * @author dmakariev
 */
//@FacesComponent(value = "compositeFileUpload")
public class UploadNamingContainer extends UINamingContainer {

    public UploadNamingContainer() {
    }

    @Override
    public String getFamily() {
        return "javax.faces.NamingContainer";
    }

    @Override
    public void decode(final FacesContext context) {

        //final String clientId = this.getClientId(context);

        //final Map<String, Object> attrs = this.getAttributes();
        // final Object o = attrs.get("value");
        final ValueExpression valueVE = this.getValueExpression("value");
        final String veString = valueVE.getExpressionString();

        final DsFileItem currentFile = getCurrentFile(context);
        if (null != currentFile) {

            final ELContext currentELContext = FacesContext.getCurrentInstance().getELContext();
            final Object fileHolder = valueVE.getValue(currentELContext);

            if (fileHolder instanceof DsFileItemAware) {
                ((DsFileItemAware) fileHolder).setDsFileItem(currentFile);
            } else {
                FacesUtils.setValueExpression(veString, currentFile);
            }
        }

        super.decode(context);
    }

    private DsFileItem getCurrentFile(final FacesContext context) {
        final String clientId = this.getClientId(context);

        if (false == FileRequestHolder.isEmpty()) {
            final DsFileItem currentFile = FileRequestHolder.getFileParameter(clientId);
            return currentFile;
        } else {
            //this is integration with PrimeFaces FileUploadFilter.
            try {
                final MultipartRequest multipartRequest = getMultiPartRequestInChain(context);
                final FileItem file = multipartRequest.getFileItem(clientId);
                if (file != null) {
                    final DsFileItem currentFile = CurrentFileImpl.fromFileItem(file);
                    return currentFile;
                }
            } catch (Exception ex) {
            }
        }
        return null;
    }

    /**
     * Finds our MultipartRequestServletWrapper in case application contains
     * other RequestWrappers
     */
    private MultipartRequest getMultiPartRequestInChain(FacesContext facesContext) {
        Object request = facesContext.getExternalContext().getRequest();

        while (request instanceof ServletRequestWrapper) {
            if (request instanceof MultipartRequest) {
                return (MultipartRequest) request;
            } else {
                request = ((ServletRequestWrapper) request).getRequest();
            }
        }

        return null;
    }
}
